<?php
/**
 * @desc 基础工具类
 * @author zhaoyang
 * @date 2018年5月4日 下午11:21:11
 */

namespace Common;

use Common\Models\AESH5Mcrypt;
use Common\Models\AppConfig;
use Common\Models\BShopUsers;
use Common\Models\BshopUsersInfo;
use Common\Models\FUserExtend;
use Common\Models\Levels;
use Common\Models\Messages;
use Common\Models\User;
use Library\ConstKey\SystemKey;
use Phalcon\Text;
use Phalcon\Crypt;
use function GuzzleHttp\Psr7\str;

class Common{

    /**
     * @func 获取一个时间节点
     * @param $time_type 1 今日 2 昨日 3 近七天 4 15天 5 30天 6 60天 7 90天 8 本月 9 上月 10前天 11近三天 12半年 13今年 14本周 15近30天
     * @return array
     */
    public static function timeChange($time_type)
    {
        switch ($time_type) {
            case 1:
                //获取今日开始时间戳和结束时间戳
                $start = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
                $end = mktime(0, 0, 0, date('m'), date('d') + 1, date('Y')) - 1;
                break;
            case 2:
                //获取昨日开始时间戳和结束时间戳
                $start = mktime(0, 0, 0, date('m'), date('d') - 1, date('Y'));
                $end = mktime(0, 0, 0, date('m'), date('d'), date('Y')) - 1;
                break;
            case 3:
                //获取七天开始时间戳和结束时间戳
                $start = mktime(0, 0, 0, date('m'), date('d') - 6, date('Y'));
                $end = mktime(23, 59, 59, date('m'), date('d'), date('Y'));
                break;
            case 4:
                //获取15天
                $start = mktime(0, 0, 0, date('m'), date('d') - 14, date('Y'));
                $end = mktime(23, 59, 59, date('m'), date('d'), date('Y'));
                break;
            case 5:
                //获取30天
                $start = mktime(0, 0, 0, date('m'), date('d') - 29, date('Y'));
                $end = mktime(23, 59, 59, date('m'), date('d'), date('Y'));
                break;
            case 6:
                //获取60天
                $start = mktime(0, 0, 0, date('m'), date('d') - 59, date('Y'));
                $end = mktime(23, 59, 59, date('m'), date('d'), date('Y'));
                break;
            case 7:
                //获取90天
                $start = mktime(0, 0, 0, date('m'), date('d') - 89, date('Y'));
                $end = mktime(23, 59, 59, date('m'), date('d'), date('Y'));
                break;
            case 8:
                //获取本月
                $start = mktime(0, 0, 0, date('m'), 1, date('Y'));
                $end = mktime(23, 59, 59, date('m'), date('t'), date('Y'));
                break;
            case 9:
                //获取上月
                $start = mktime(0, 0, 0, date('m')-1, 1, date('Y'));
                $end = mktime(23, 59, 59, date('m'), 1-1, date('Y'));
                break;
            case 10:
                //获取前天开始时间戳和结束时间戳
                $start = mktime(0, 0, 0, date('m'), date('d') - 2, date('Y'));
                $end = $start+86399;
                break;
            case 11:
                //获取三天开始时间戳和结束时间戳
                $start = mktime(0, 0, 0, date('m'), date('d') - 2, date('Y'));
                $end = mktime(23, 59, 59, date('m'), date('d'), date('Y'));
                break;
            case 12:
                //获取半年开始时间戳和结束时间戳
                $start = mktime(0, 0, 0, date('m'), date('d') - 179, date('Y'));
                $end = mktime(23, 59, 59, date('m'), date('d'), date('Y'));
                break;
            case 13:
                //获取一年开始时间戳和结束时间戳
                $start = strtotime(date('Y-')."01-01 00:00:00");
                $end = strtotime(date('Y-')."12-31 23:59:59");
                break;
            case 14:
                //获取本周的时间
                $start = strtotime(date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1,date("Y"))));
                $end = strtotime(date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y"))));
                break;
            case 15:
                //获取七天开始时间戳和结束时间戳
                $start = mktime(0, 0, 0, date('m'), date('d') - 29, date('Y'));
                $end   = mktime(23, 59, 59, date('m'), date('d'), date('Y'));
                break;
        }
        $times = array('start_at' => date("Y-m-d H:i:s", $start), 'end_at' => date("Y-m-d H:i:s", $end));
        return $times;
    }


    /**
     * @param $request_url 请求地址
     * @param $request_data 请求参数
     * @return bool|mixed|string 请求结果
     */
    public static function request_post($url,$params,$type=1,$headers=[]){
        try {
            if($headers){
                $headers[] = 'Content-Type:application/x-www-form-urlencoded;charset=utf-8';
            }
            $curl = curl_init(); // 启动一个CURL会话
            curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); // 从证书中检查SSL加密算法是否存在
            //curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
            curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
            curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
            curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
            if($type == 1){
                curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params)); // Post提交的数据包
            } else {
                curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params)); // Post提交的数据包
            }

            curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
            curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            $result = curl_exec($curl); // 执行操作
            if (curl_errno($curl)) {
                return ['status' => false, 'msg' => 'Errno' . curl_error($curl), 'data' => []];
            }
            curl_close($curl); // 关闭CURL会话
            $res = json_decode($result, true);
            if (!$res) {
                return ['status' => false, 'msg' => '获取不到json数据', 'data' => []];
            } else {
                return ['status' => true, 'msg' => '获取成功', 'data' => $res];
            }
        } catch (\Exception $e) {
            return ['status' => false, 'msg' => $e->getMessage(), 'data' => []];
        }
    }


    /**
     * @param $url 请求地址
     * @return bool|string 请求结果
     */
    public static function request_get($url){
        try {
            //初始化
            $curl = curl_init();
            //设置抓取的url
            curl_setopt($curl, CURLOPT_URL, $url);
            //设置头文件的信息作为数据流输出
            curl_setopt($curl, CURLOPT_HEADER, false);
            //设置获取的信息以文件流的形式返回，而不是直接输出。
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            //执行命令
            $data = curl_exec($curl);
            //关闭URL请求
            curl_close($curl);
            //显示获得的数据
            $data_array = json_decode($data, true);
            if ($data_array) {
                return ['status' => true, 'msg' => '获取成功', 'data' => $data_array];
            } else {
                return ['status' => false, 'msg' => '获取不到json数据', 'data' => []];
            }
        } catch (\Exception $e) {
            return ['status' => false, 'msg' => $e->getMessage(), 'data' => []];
        }
    }


    /**
     * 获取本地域名
     */
    public static function domain(){
        if ( !empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
            $url = 'https://';
        } elseif ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
            $url = 'https://';
        } elseif ( !empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
            $url = 'https://';
        }else{
            $url = 'http://';
        }
        $url = $url.$_SERVER['HTTP_HOST'];
        return $url;
    }


    /**
     * 对象转数组
     */
    public static function transition_array($obj,$page=''){
        $arr_str = json_encode($obj);
        $arr_json = json_decode($arr_str,true);
        if(!empty($page)) {
            if ($arr_json['total_pages'] < $page) {
                $arr_json['items'] = [];
                $arr_json['current'] = $page;
                return $arr_json;
            }
        }
        return $arr_json;
    }



    /**
     * @param $path 路径
     * @param $referer_id 父级id
     */
    public static function invite($referer_id,$path){     //父级id
        $user = new User();
        $referer_user = $user->find_by_firstId($referer_id);
        if(!empty($referer_user)) {
            $referer_user['direct_vip'] = $referer_user['direct_vip'] + 1;      //父级直邀人数加1
            $referer_user['team_scale'] = $referer_user['indirect_vip'] + $referer_user['direct_vip'];
            $user->save_user($referer_user);
            if ($path) {
                $indirect_ids = explode(',', $path);
                foreach ($indirect_ids as $key => $value) {
                    $user1 = new User();
                    $indirect_user = $user->find_by_firstId($value);
                    if ($indirect_user) {
                        $indirect_user['indirect_vip'] = $indirect_user['indirect_vip'] + 1;    //path里面的人数加1
                        $indirect_user['team_scale'] = $indirect_user['direct_vip'] + $indirect_user['indirect_vip'];
                        $user1->save_user($indirect_user);
                    }
                }
            }
        }
    }


    /**
     * 分页
     */
    public static function paging($list,$count,$page_size,$page){
        if(round($count/$page_size) == 0){
            $total_page = 1;
        }else{
            $total_page = $count/$page_size;
        }
        $data['items'] = $list;
        $data['first'] = 1;
        $data['before'] = $page>1 ? $page-1:$page;
        $data['current'] = $page;
        $data['last'] =  $count>0 ? (int)$total_page : 0;
        $data['next'] = (int)$total_page > $page+1 ? $page+1 : $page;
        $data['total_pages'] = $count>0 ? (int)$total_page : 0;
        $data['total_items'] = $count;
        $data['limit'] = $page_size;
        return $data;
    }

    /**
     * 生成商品海报
     */
    public static function goods_poster($goods){
        $share_img = $goods['PicLogo'];
        //计算原图长宽比例
        //新图尺寸
        //生成海报
        $font = APP_PATH.'public/static/simsun.ttf';   //保证字体文件目录正确
        $font_cu = APP_PATH.'public/static/songcu.ttf';   //保证字体文件目录正确
        $filepath = APP_PATH.'public/static/haibao/p.jpg';
        $posters_width = 450;                   //画布宽度
        $posters_height = 700;
        $newimg = imagecreatetruecolor($posters_width, $posters_height);
        $bg = imagecolorallocate($newimg, 244, 244, 244);
        imagefill($newimg,0,0,$bg);
        //写分享图片
        $new_shareim = imagecreatefromstring(file_get_contents($share_img));
        imagecopy($newimg,$new_shareim,0,0,0,0,450,350);      //写入商品图片

        //-----------------------------------------------------------商品相关----------------------------------
        $filepath_goods = APP_PATH.'public/static/haibao/goods_p.jpg';
        $posters_width = 450;                   //画布宽度
        $posters_height = 220;
        $goods_newimg = imagecreatetruecolor($posters_width, $posters_height);
        $goods_bg = imagecolorallocate($goods_newimg, 255, 255, 255);
        imagefill($goods_newimg,0,0,$goods_bg);
        //商品标题
        $black = imagecolorallocate($goods_newimg, 0, 0, 0);
        $title =  mb_substr($goods['Title'], 0, 11, 'utf-8').'...';
        imagettftext($goods_newimg,15,0,30,40,$black,$font_cu,$title);
        $black = imagecolorallocate($goods_newimg, 176, 176, 176);
        imagettftext($goods_newimg,12,0,30,80,$black,$font,"{$goods['MonthSale']}人已购买");
        $black = imagecolorallocate($goods_newimg, 255, 0, 0);
        imagettftext($goods_newimg,13,0,30,120,$black,$font,'券后￥');
        imagettftext($goods_newimg,20,0,100,120,$black,$font_cu,"{$goods['EndPrice']}");
        $black = imagecolorallocate($goods_newimg, 176, 176, 176);
        imagettftext($goods_newimg,10,0,185,120,$black,$font,"原价{$goods['Price']}");
        imagettftext($goods_newimg,12,0,180,120,$black,$font,'----------');
        $share_img = 'http://jzcloud.jiruan.ltd/font/juan.png';
        $new_shareim = imagecreatefromstring(file_get_contents($share_img));
        imagecopy($goods_newimg,$new_shareim,30,150,0,0,99,30);      //写入商品图片
        $black = imagecolorallocate($goods_newimg, 255, 255, 255);
        imagettftext($goods_newimg,15,0,30,172,$black,$font_cu," 卷 {$goods['CouponMoney']}元");
        //写二维码
        require_once "phpqrcode.php";
        $errorCorrectionLevel = 'L';  //容错级别
        $matrixPointSize = 4;      //生成图片大小
        //生成二维码图片
        ob_start();
        QRcode::png("{$goods['turn_url']}",false,$errorCorrectionLevel, $matrixPointSize, 2);
        $imgstr = 'data:image/png;base64,'.base64_encode(ob_get_contents());
        //$imgstr =base64_encode(ob_get_contents());
        ob_end_clean();
        if (strstr($imgstr,",")){
            $imgstr = explode(',',$imgstr);
            $imgstr = $imgstr[1];
        }
        $imageName = APP_PATH.'public/static/haibao/'.date("His",time())."_".rand(1111,9999).'.jpg';
        $ostream_image = file_put_contents($imageName, base64_decode($imgstr));//返回的是字节数
        if($ostream_image) {
            //$er_shareim = imagecreatefromstring(file_get_contents('http://jzcloud.jiruan.ltd/img/ad/tb.png'));
            $er_shareim = imagecreatefromstring(file_get_contents($imageName));
            imagecopy($goods_newimg, $er_shareim, 260, 5, 0, 0, 150, 150);
            $gray = imagecolorallocate($goods_newimg, 136, 136, 136);
            @unlink($imageName);
        }
        $black = imagecolorallocate($goods_newimg, 144, 144, 144);
        imagettftext($goods_newimg,10,0,285,175,$black,$font,'长按二维码领劵');

        //海报生成保存
        imagejpeg($goods_newimg, $filepath_goods);
        ImageDestroy($goods_newimg);
        $new_shareim = imagecreatefromstring(file_get_contents($filepath_goods));
        imagecopy($newimg,$new_shareim,10,370,0,0,430,200);      //写入商品图片
        $changan = APP_PATH."public/static/haibao/changan.jpg";//http://jzcloud.jiruan.ltd/font/changan.jpg
        $new_shareim = imagecreatefromstring(file_get_contents($changan));
        imagecopy($newimg,$new_shareim,0,560,0,0,450,133);      //写入商品图片
        //海报生成保存
        imagejpeg($newimg, $filepath);
        ImageDestroy($newimg);
        $base64_file = '';
        if(file_exists($filepath)){
            $mime_type= mime_content_type($filepath);
            $base64_data = base64_encode(file_get_contents($filepath));
            //$base64_file = 'data:'.$mime_type.';base64,'.$base64_data;
            $base64_file = $base64_data;
        }
        return $base64_file;
    }


    /**
     * 获取用户的ip
     */
    public static function get_real_ip()
    {
        $ip=false;
        if(!empty($_SERVER["HTTP_CLIENT_IP"])){
            $ip = $_SERVER["HTTP_CLIENT_IP"];
        }
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
            $ips = explode (", ", $_SERVER['HTTP_X_FORWARDED_FOR']);
            if($ip){
                array_unshift($ips, $ip); $ip = FALSE;
            }
            for($i = 0; $i < count($ips); $i++){
                if (!eregi ("^(10|172\.16|192\.168)\.", $ips[$i])){
                    $ip = $ips[$i];
                    break;
                }
            }
        }
        return($ip ? $ip : $_SERVER['REMOTE_ADDR']);
    }


    /**
     * 判断日期是否是合法的
     */
    public static function is_datatime($data){
        $date=strtotime($data);
        if($data==(date("Y-m-d", $date))|| $data==(date("Y-m-j", $date))||$data==(date("Y-n-d", $date))||$data==(date("Y-n-j", $date)))
            return true;
        else
            return false;
    }



    /**
     * 计算两个时间之差
     * @param $time
     * @return string
     */
    public static function format_date($date){
        $time = strtotime($date);
        $t=time()-$time;
        $f=array(
            '31536000'=>'年',
            '2592000'=>'个月',
            '604800'=>'星期',
            '86400'=>'天',
            '3600'=>'小时',
            '60'=>'分钟',
            '1'=>'秒'
        );
        foreach ($f as $k=>$v)    {
            if (0 !=$c=floor($t/(int)$k)) {
                return $c.$v.'前';
            }
        }
    }


    /**
     * 返回用户的昵称和电话号码
     */
    public static function get_username_phone($user_id){
        $user_obj = new User();
        $user_info = $user_obj->find_by_id($user_id)->toarray();
        if ($user_info['nickname'] || $user_info['wx_nickname'] || $user_info['phone']) {             //获取当前我的昵称 判断 以前的nickname 后面添加了一个wx_nickname 如果没有的话就取电话号码
            $username = $user_info['nickname'] ? $user_info['nickname'] : $user_info['wx_nickname'];
            if (empty($username)) {
                $phone = substr_replace($user_info['phone'], '****', 3, 4);
                $username = $phone;
            }
        } else {
            $username = '没有填写';
        }
        $phone = substr_replace($user_info['phone'], '****', 3, 4);
        $avatar = $user_info['avatar'];
        $levelDb = new Levels();
        $level = $levelDb->find_by_id($user_info['level_id']);
        $result['invite_code'] = !empty($user_info['exclusive_code']) ? $user_info['exclusive_code'] : $user_info['invite_code'];
        $result['weixin_no'] = $user_info['weixin_no'];
        $result['nickname']=$username;
        $result['phone']=$phone;
        $result['real_name'] = $user_info['real_name'];
        $result['avatar']=$avatar;
        $result['level_id']=isset($level['id']) ? $level['id'] : 1;
        $result['level_name']=isset($level['name']) ? $level['name'] : '会员';
        $result['level_icon']=isset($level['icon']) ? $level['icon'] : '';
        $result['tb_rid']=isset($user_info['tb_rid']) && !empty($user_info['tb_rid']) ? $user_info['tb_rid'] : '';
        $result['is_privacy']=$user_info['is_privacy'];
        $result['alipay_account']=$user_info['alipay_account'];
        //$result['password']=$user_info['password'];
        $result['real_phone']= $user_info['phone'];
        $result['tb_special_id'] = isset($user_info['tb_special_id']) && !empty($user_info['tb_special_id']) ? $user_info['tb_rid'] : '';

        $BShopUserDb = new BShopUsers();
        $shop_users = $BShopUserDb->findFirstByUserId($user_info['id']);
        if(!$shop_users){
            $result['is_shop_status'] = 0;
            $result['shop_status_tips']='您还未申请过';
        }
        $result['is_shop_status'] = (int)$shop_users->status;
        $result['shop_status_tips'] = $shop_users->status_tips;
        $result['h5_token'] = "dddd";
        return $result;
    }


    //对小数不进行四舍五入
    public static function number_randtwo($number){
        return substr(sprintf("%.3f", $number),0,-1);
    }



    //验证时间是否正确
    public static function valid_date($date)
    {
        if(date('Y-m-d H:i:s',strtotime($date)) == $date)
        {
            return true;
        }else{
            return false;
        }
    }

    //转换参数
    public static function convertUrlQuery($url){
        $arr = parse_url($url);
        if(isset($arr['query'])) {
            $queryParts = explode('&', $arr['query']);
            $params = array();
            foreach ($queryParts as $param) {
                $item = explode('=', $param);
                $params[$item[0]] = $item[1];
            }
            return $params;
        }else{
            return [];
        }
    }


    //根据当前时间返回上一月的
    public static function up_month($datetime){
        $change_time = strtotime($datetime);
        $datetime = mktime(0, 0, 0, date('m',$change_time)+1, 1, date('Y',$change_time));
        $datetime = date('Y年m月',$datetime);
        return $datetime;
    }


    //定义路由
    public static function router($name,$path,$type,$redrict,$url,$is_tb_atuh='0'){
        {
            $data['name'] = $name;
            $data['path'] = $path;
            $data['change_style'] = "0";
            $data['route']['id'] = "0";
            $data['route']['type'] = $type.'';
            $data['route']['path'] = $redrict;
            $data['route']['is_tb_atuh'] = $is_tb_atuh;
            $data['route']['is_need_login'] = "1";
            $data['route']['title'] = $name;
            $data['route']['url'] = $url;
            $data['route']['data'] = "";
            $data['route']['relationId'] = "1";
            return $data;
        }
    }


    /**
     * 可逆字符串解密
     * @param string $txt 加密过的字符串
     * @param bool $off 是否开启加密
     * @return string
     */
    public static function auth_decode($txt, $off = false)
    {
        if ($off == true) {
            if (!$txt) {
                return false;
            }
            $key   = 'webHttpFrameWork@2020#!Fuck Me';
            $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.";
            $ikey  = "x6g6ZWm2G9g_vr0Bo.pOq3kRIxsZ6rmFuck";
            $knum  = 0;
            $i     = 0;
            $tlen  = strlen($txt);
            while (isset($key[$i]))
                $knum += ord($key[$i++]);
            $ch1   = $txt[$knum % $tlen];
            $nh1   = strpos($chars, $ch1);
            $txt   = substr_replace($txt, '', $knum % $tlen--, 1);
            $ch2   = $txt[$nh1 % $tlen];
            $nh2   = strpos($chars, $ch2);
            $txt   = substr_replace($txt, '', $nh1 % $tlen--, 1);
            $ch3   = $txt[$nh2 % $tlen];
            $nh3   = strpos($chars, $ch3);
            $txt   = substr_replace($txt, '', $nh2 % $tlen--, 1);
            $nhnum = $nh1 + $nh2 + $nh3;
            $mdKey = substr(md5(md5(md5($key . $ch1) . $ch2 . $ikey) . $ch3), $nhnum % 8, $knum % 8 + 16);
            $tmp   = '';
            $j     = 0;
            $k     = 0;
            $tlen  = strlen($txt);
            $klen  = strlen($mdKey);
            for ($i = 0; $i < $tlen; $i++) {
                $k = $k == $klen ? 0 : $k;
                $j = strpos($chars, $txt[$i]) - $nhnum - ord($mdKey[$k++]);
                while ($j < 0)
                    $j += 64;
                $tmp .= $chars[$j];
            }
            $tmp = str_replace(['-', '_', '.'], ['+', '/', '='], $tmp);
            return trim(base64_decode($tmp));
        } else {
            return $txt;
        }

    }



    /**
     * 加密
     * @param $txt
     * @param $off 加密开关
     * @return false|string|string[]
     */
    public static function auth_encode($txt, $off = false)
    {
        if ($off == true) {
            if (!$txt) {
                return false;
            }
            $key   = 'webHttpFrameWork@2020#!Fuck Me';
            $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.";
            $ikey  = "x6g6ZWm2G9g_vr0Bo.pOq3kRIxsZ6rmFuck";
            $nh1   = 1;
            $nh2   = 1;
            $nh3   = 1;
            //$nh1 = rand(0, 32);
            //$nh2 = rand(0, 32);
            //$nh3 = rand(0, 32);
            $ch1   = $chars[$nh1];
            $ch2   = $chars[$nh2];
            $ch3   = $chars[$nh3];
            $nhnum = $nh1 + $nh2 + $nh3;
            $knum  = 0;
            $i     = 0;
            while (isset($key[$i]))
                $knum += ord($key[$i++]);
            $mdKey = substr(md5(md5(md5($key . $ch1) . $ch2 . $ikey) . $ch3), $nhnum % 8, $knum % 8 + 16);
            $txt   = base64_encode($txt);
            $txt   = str_replace(['+', '/', '='], ['-', '_', '.'], $txt);
            $tmp   = '';
            $j     = 0;
            $k     = 0;
            $tlen  = strlen($txt);
            $klen  = strlen($mdKey);
            for ($i = 0; $i < $tlen; $i++) {
                $k   = $k == $klen ? 0 : $k;
                $j   = ($nhnum + strpos($chars, $txt[$i]) + ord($mdKey[$k++])) % 64;
                $tmp .= $chars[$j];
            }
            $tmplen = strlen($tmp);
            $tmp    = substr_replace($tmp, $ch3, $nh2 % ++$tmplen, 0);
            $tmp    = substr_replace($tmp, $ch2, $nh1 % ++$tmplen, 0);
            $tmp    = substr_replace($tmp, $ch1, $knum % ++$tmplen, 0);
            return $tmp;
        } else {
            return $txt;
        }
    }



    /**
     * @desc 将数组中键名下划线转换为驼峰
     * @param array|object $arr
     * @param bool $lcfirst 首字母是否小写
     * @return mixed
     * @author zhaoyang
     * @date 2018年5月4日 下午11:22:21
     */
    public static function convertArrKeyUnderline($arr, $lcfirst = true)
    {
        $type = is_array($arr) ? 1 : (is_object($arr) ? 2 : 0);
        if ($type) {
            foreach ($arr as $k => $v) {
                $key = $k;
                if (strpos($key, '_') !== false) {
                    $key = Text::camelize($key);
                    $lcfirst && $key = lcfirst($key);
                    if ($type == 1) {
                        unset($arr[$k]);
                    } else {
                        unset($arr->$k);
                    }
                }
                if (is_array($v) || is_object($v)) {
                    $v = static::convertArrKeyUnderline($v);
                }
                if ($type == 1) {
                    $arr[$key] = $v;
                } else {
                    $arr->$key = $v;
                }
            }
        }
        return $arr;
    }


    /**
     * @desc 创建目录
     * @param string $pathname 路径
     * @param int $mode 文件夹权限默认情况下，模式是0777
     * @param bool $recursive 规定是否设置递归模式
     * @param resource $context 规定文件句柄的环境。Context 是可修改流的行为的一套选项。
     * @return bool
     * @author zhaoyang
     * @date 2018年5月4日 下午11:21:43
     */
    public static function mkdir($pathname, $mode = 0777, $recursive = true, $context = null)
    {
        if (empty($pathname)) {
            return false;
        }
        if (is_dir($pathname)) {
            return true;
        }
        return is_resource($context) ? mkdir($pathname, $mode, $recursive, $context) : mkdir($pathname, $mode, $recursive);
    }


    /**
     * 高精度计算 不进行四舍5入 直接舍弃
     * @param string $one 第一位数
     * @param string $two 第二位数
     * @param int $type 计算方式符号
     * @param int $precision 精确位数
     * @param int $encrypt 是否加密 是 否
     * @param int $one_encrypt 第一位数是否加密 是 否
     * @param int $two_encrypt 第二位数是否加密 是 否
     * @return int|string
     * bcadd — 将两个高精度数字相加
     * bccomp — 比较两个高精度数字，返回【0表示 相同】 【1 表示 num1大】 【-1 表示 num2 大 或 其他】
     * bcdiv — 将两个高精度数字相除
     * bcmod — 求高精度数字余数
     * bcmul — 将两个高精度数字相乘
     * bcpow — 求高精度数字乘方
     * bcpowmod — 求高精度数字乘方求模，数论里非常常用
     * bcscale — 配置默认小数点位数，相当于就是Linux bc中的”scale=”
     * bcsqrt — 求高精度数字平方根
     * bcsub — 将两个高精度数字相减
     *
     */
    public static function bc($one, $two, $type = '+',$precision = 2,$one_encrypt = 0,$two_encrypt = 0,$encrypt = 0)
    {
        $one = $one ? $one : 0;
        $two = $two ? $two : 0;
        if ($one) {
            $one = self::etodec((string)$one);
        }
        if ($two) {
            $two = self::etodec((string)$two);
        }
        if ($one_encrypt == 1) {
            $one = self::auth_decode($one);
        }
        if ($two_encrypt == 1) {
            $two = self::auth_decode($two);
        }
        if ($type == '+') {//将两个高精度数字相加
            $res = bcadd($one, $two, $precision);
        }

        if ($type == '-') {//将两个高精度数字相减
            $res = bcsub($one, $two, $precision);
        }

        if ($type == '*') {//将两个高精度数字相乘
            $res = bcmul($one, $two, $precision);
        }

        if ($type == '/') {//将两个高精度数字相除
            $res = bcdiv($one, $two, $precision);
        }

        if ($type == '<>') {
            // 【0表示 相同】 【1 表示 num1大】 【-1 表示 num2 大 或 其他】
            return bccomp($one, $two, $precision);
        }

        if ($encrypt == 1) {
            return self::auth_encode($res);
        }
        return $res ? $res : 0;
    }



    /**
     * 把1e+06变成10进制的普通计数法的
     * @param $num
     * @return float|int
     * author:dengjing
     * date:2020/11/25 11:22 上午
     */
    public static function etodec($num)
    {
        $array = explode('E', $num);
        if (!isset($array[1])) {
            return $num;
        }
        $base = (int)$array[0];
        $pow = $array[1];
        switch ($pow) {
            case '-1';
                $result = '0.' . $base;
                break;
            case '-2';
                $result = '0.0' . $base;
                break;
            case '-3';
                $result = '0.00' . $base;
                break;
            case '-4';
                $result = '0.000' . $base;
                break;
            case '-5';
                $result = '0.0000' . $base;
                break;
            case '-6';
                $result = '0.00000' . $base;
                break;
            default;
                $result = 0;
        }
        return $result;
    }


    /**
     * @desc 格式化目录
     * @author zhaoyang
     * @date 2018年5月4日 下午11:21:27
     */
    public static function dirFormat(string $path)
    {
        $path = str_replace('\\', '/', $path);
        $path = preg_replace_callback('/(\{.+\})/U', function ($matches) {
            return date(rtrim(ltrim($matches[0], '{'), '}'));
        }, $path);
        return $path;
    }

    /**
     * 生成唯一订单号
     */
    public static function order_sn($prefix){
        return $prefix . date('YmdHis', time()) . substr(microtime(), 2, 6) . sprintf('%03d', rand(0, 999));
    }


    /**
     * 获取快递信息
     */
    public static function express_list($express_sn){
        $url = "http://www.kuaidi.com/index-ajaxselectcourierinfo-{$express_sn}-shentong-KUAIDICOM1624862938561.html";
        $headers[]  =  "Content-Type:application/json";
        $headers[]  =  "Cookie: lang=zh-cn; theme=default; sid=hqc1qpdlivas8go6ujrgeg30h0; UM_distinctid=179ca9ef9dad3-02c79d607b9227-3f356b-1fa400-179ca9ef9db9f; __gads=ID=ec6a9f73a3f441c3-2296dd961fc900be:T=1622602086:RT=1622602086:S=ALNI_MZjzs8qdIf8V_ih7GJkqoss1aw5Cg; CNZZDATA1254194234=983217441-1622596741-null%7C1624862920";
        $headers[]  =  "Host: www.kuaidi.com";
        $headers[]  =  "Origin: http://www.kuaidi.com";
        $headers[]  =  "Referer: http://www.kuaidi.com/";
        $headers[]  =  "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36";
        $headers[]  =  "X-Requested-With: XMLHttpRequest";
        $curl = curl_init();
        //设置抓取的url
        curl_setopt($curl, CURLOPT_URL, $url);
        //设置头文件的信息作为数据流输出
        curl_setopt($curl, CURLOPT_HEADER,0);
        //设置请求头
        curl_setopt($curl, CURLOPT_HTTPHEADER,$headers);
        //设置获取的信息以文件流的形式返回，而不是直接输出。
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        //设置post方式提交
        curl_setopt($curl, CURLOPT_POST, 1);
        //设置post数据
        $post_data = '';
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
        //执行命令
        $data = curl_exec($curl);
        //关闭URL请求
        curl_close($curl);
        //显示获得的数据
        return json_decode($data);
    }



    //计算佣金收入
    public static function commission($user_id,$moeny){
        $appconfig = new AppConfig();
        $app_list = $appconfig->find_list("commission");
        $data['rate_commission'] =$app_list['taobao_commission'];
        $data['rate_money'] = $moeny * $app_list['taobao_commission'];
        $data['commisson'] = $moeny - $data['rate_money'];
        $commission = $appconfig->find_level_key($user_id);
        $data['my_commisson'] = substr(sprintf("%.3f", $commission['my_commisson'] * $data['commisson']),0,-1);
        $data['max_commisson'] = substr(sprintf("%.3f", $commission['max_commisson'] * $data['commisson']),0,-1);
        return $data;
    }


    /**
     * 获取分佣佣金
     */
    public static function self_CalculatingMoney($user_id,$commission,$pay_money=0){
        $res['commition']=self::self_commition($user_id,$commission,$pay_money);//佣金收入
        return $res;
    }


    /**
     * 自己所分的佣金百分比
     */
    public static function self_commition($user_id,$commission,$pay_money=0){
        //佣金所分百分比配置表
        $appconfig = new AppConfig();
        $config_commission = $appconfig->find_list('commission');
        if(!$config_commission){
            $config_commission['level1']=0.4;
            $config_commission['level2']=0.45;
            $config_commission['level3']=0.5;
            $config_commission['level4']=0.55;
            $config_commission['level5']=0.6;
            $config_commission['level6']=0.65;
            $config_commission['level7']=0.7;
            $config_commission['percent_money']=0.2;                //团队分钱百分比
            $config_commission['direct_money']=0.3;                 //团队的直邀分钱百分比
            $config_commission['team_money']=0.2;                   //团队的团队分钱百分比
            $config_commission['ping_money']=0.05;                  //平级所分的钱
            $config_commission['jicha_money']=0.01;                  //团队所分的级差点
        }
        $user = new User();
        $money_arr = [];
        $buyer_obj = $user->find_by_id($user_id);
        if(!$buyer_obj){     //当前的用户没有找到的时候
            return $money_arr;
        }
        $self_leveld= 'level'.$buyer_obj->level_id;
        $self_money = $config_commission[$self_leveld] * $commission;
        $money_arr[0]=[                                                         //自己分钱
            'number'=>$self_money > 0 ? 1 : 0,                                  //是否可以分到钱
            'buyer'=>$buyer_obj->id,
            'percent'=>self::bc($self_money,'0','+'),
            'id'=>$buyer_obj->id
        ];
        if($buyer_obj->path){
            $buyer_up_user = $buyer_obj->path.','.$buyer_obj->referer_id;
        }else{
            $buyer_up_user = $buyer_obj->referer_id;
        }
        if(empty($buyer_up_user)){
            $buyer_up_user=-1;
        }
        $conditions="id in($buyer_up_user) and is_appuser<>0";
        $buyer_up_user_arr = $user->find(
            array(
                $conditions,
                'columns'=>'id,level_id',
                'order'=>'id desc',
                'limit'=>2
            )
        )->toarray();
        $team_money_arr=[];
        $team_money = $config_commission['percent_money'] * $commission;            //团队应该分的钱
        $direct_money=0;
        foreach($buyer_up_user_arr as $key=>$value){
            if($value['id'] == 1){
                continue;
            }
            if($direct_money>$team_money){                                          //控制要分的钱不能超过总的分钱数
                break;
            }
            if($key == 0){
                $current_money = $config_commission['direct_money'] * $team_money + (($value['level_id']-1)/100)*$team_money;        //直推下级所拿的钱
                $direct_money = $current_money+$direct_money;
                $team_money_arr[$key]['number']=$current_money > 0 ? 1 : 0;
                $team_money_arr[$key]['buyer']=$buyer_obj->id;
                $team_money_arr[$key]['percent']=self::bc($current_money,'0','+');
                $team_money_arr[$key]['id']=$value['id'];
            }else{
                $current_money = $config_commission['team_money'] * $team_money;            //联盟所分的钱
                $jicha_money = ($value['level_id']-$buyer_obj->level_id)*$config_commission['jicha_money'] * $current_money;      //级差所分的钱
                $ping_money = self::bc($team_money,$config_commission['ping_money'],'*');                                                             //平级所分的钱
                if($value['level_id'] > $buyer_obj->level_id){                                                             //判断当前人是拿级差奖还是拿平级奖
                    $percent = $jicha_money;
                }else{
                    $percent = $ping_money;
                }

                $direct_money = $jicha_money+$percent+$direct_money;                                                     //已经分的钱的总和
                if($direct_money < $team_money){                                                            //当前联盟所分的钱是否已经超过了
                    $team_money_arr[$key]['number']=1;
                    $team_money_arr[$key]['buyer']=$buyer_obj->id;
                    $team_money_arr[$key]['percent']=self::bc($percent,'0','+');
                    $team_money_arr[$key]['id']=$value['id'];
                }
            }
        }
        $money_arr = array_merge($money_arr,$team_money_arr);
        return $money_arr;
    }


    /**
     * 生成redis的Key
     */
    public static function redisKey($params){
        $array_value = array_values($params);
        $str_keys = implode("_",$array_value);
        $str_keys = SystemKey::PROJECTNAME.":".$str_keys;
        return $str_keys;
    }
}

